//////////////////////////////////////////////////////////////////////
// MousePicker.h
//
// SHEN Fangyang
// me@shenfy.com
//
// Copyright (C) SHEN Fangyang, 2011, All rights reserved.
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
//  Brief Description
//
//	Convert mouse click to line in world coord system
//
//////////////////////////////////////////////////////////////////////
#pragma once
#include <BasisObj.h>
#include <boost/function.hpp>

namespace grflib
{
    namespace engine
    {
        namespace aux
        {
            class CMousePicker : public grflib::engine::core::IInteractive
            {
            public:
                enum Action {ACT_NONE = 0, ACT_INVOKE_HOOK, ACT_INVOKE_TARGET_FUNC, ACT_NOTIFY_TARGET};
                enum ButtonMask {BTN_NONE = 0x0, BTN_LEFT = 0x1, BTN_RIGHT = 0x2, BTN_MIDDLE = 0x4};

            public:
                CMousePicker();
                ~CMousePicker();

                virtual HRESULT OnGUIEvent(UINT nEvent, int nControlID, CDXUTControl *pControl) {return S_OK;}
                virtual HRESULT OnKey(UINT nChar, bool bKeyDown, bool bAltDown) {return S_OK;}

                virtual HRESULT OnMouse(bool bLeftButtonDown, bool bRightButtonDown, bool bMiddleButtonDown, 
                    bool bSideButton1Down, bool bSideButton2Down, 
                    int nMouseWheelDelta, int xPos, int yPos);
                
                virtual void GetEyeParams(D3DXVECTOR3 _out_ &vEyePos,
                    const D3DXMATRIX _out_ **mView,
                    const D3DXMATRIX _out_ **mProj);

                HRESULT CalcEyeDir(D3DXVECTOR3 &viewDir, 
					const D3DXVECTOR3 &vEyePos, 
                    const D3DXMATRIX *mView,
                    const D3DXMATRIX *mProj,
                    UINT x, UINT y, UINT iViewport = 0);
                
                void SetPickingEnabled(bool enabled);
                inline UINT &Action(void) {return m_action;}
                inline UINT &ButtonMask(void) {return m_buttonMask;}
                boost::function<void (const D3DXVECTOR3 &/*eye pos*/, const D3DXVECTOR3 &/*view dir*/)> &HookFunc(void) {return m_hookFunc;}

            protected:
                UINT m_action;
                UINT m_buttonMask;
                D3DXVECTOR3 m_vViewDir;
                UINT m_currentViewport;
                boost::function<void (const D3DXVECTOR3 &/*eye pos*/, const D3DXVECTOR3 &/*view dir*/)> m_hookFunc;
            };
        } // namespace aux
    } //namespace engine
} //namespace grflib